package com.example.project.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.example.project.entity.Issue;
import com.example.project.entity.IssueCategoryStats;
import com.example.project.entity.IssueProcessingStats;
import com.example.project.entity.IssueStatus;
import com.example.project.entity.User;
import com.example.project.mapper.IssueCategoryStatsMapper;
import com.example.project.mapper.IssueMapper;
import com.example.project.mapper.IssueProcessingStatsMapper;
import com.example.project.service.CommonService;
import com.example.project.service.IssueService;
import com.example.project.service.IssueStatsService;

/**
 * 需求处理统计服务实现类
 */
@Service
public class IssueStatsServiceImpl extends BaseServiceImpl implements IssueStatsService {

	@Autowired
	private IssueMapper issueMapper;

	@Autowired
	private IssueProcessingStatsMapper processingStatsMapper;

	@Autowired
	private IssueCategoryStatsMapper categoryStatsMapper;

	@Autowired
	private CommonService commonService;

	@Autowired
	private IssueService issueService;

	@Override
	public Map<String, Object> getSimilarIssueStats(Issue issue) {
		Map<String, Object> result = new HashMap<>();

		// 获取类别统计数据
		IssueCategoryStats categoryStats = getCategoryStats(issue.getCategoryId(), issue.getTrackerId(),
				issue.getPriorityId(), issue.getProjectId());

		if (categoryStats != null) {
			result.put("categoryStats", categoryStats);

			// 获取同类需求的历史处理记录
			List<IssueProcessingStats> similarHistory = getSimilarIssueHistory(issue, 10);
			result.put("similarHistory", similarHistory);

			// 计算预测处理时间
			if (categoryStats.getAvgProcessingTimeHours() != null) {
				result.put("estimatedProcessingTime", categoryStats.getAvgProcessingTimeHours());
			}

			// 计算推荐处理人
			Map<String, Object> recommendedAssignee = getRecommendedAssignee(issue);
			result.put("recommendedAssignee", recommendedAssignee);
		}

		return result;
	}

	@Override
	@Transactional
	public boolean recordIssueProcessingStats(Long issueId, Integer operationType, Long statusFrom, Long statusTo) {
		try {
			// 获取需求信息
			Issue issue = issueMapper.selectIssuesById(issueId);
			if (issue == null) {
				return false;
			}

			// 创建处理记录
			IssueProcessingStats stats = new IssueProcessingStats();
			stats.setIssueId(issueId);
			stats.setProjectId(issue.getProjectId());
			stats.setCategoryId(issue.getCategoryId());
			stats.setTrackerId(issue.getTrackerId());
			stats.setPriorityId(issue.getPriorityId());
			stats.setAuthorId(issue.getAuthorId());
			stats.setAssignedToId(issue.getAssignedToId());
			stats.setStatusFrom(statusFrom);
			stats.setStatusTo(statusTo);
			stats.setOperationType(operationType);
			stats.setOperationTime(LocalDateTime.now());

			// 计算处理时长
			BigDecimal processingHours = calculateProcessingHours(issueId, operationType);
			if (processingHours != null) {
				stats.setProcessingHours(processingHours);
			}

			// 保存处理记录
			processingStatsMapper.insertIssueProcessingStats(stats);

			// 更新类别统计（异步执行）
			new Thread(() -> updateCategoryStats(issue.getCategoryId())).start();

			return true;
		} catch (Exception e) {
			return false;
		}
	}

	@Override
	public IssueCategoryStats getCategoryStats(Long categoryId, Long trackerId, Long priorityId, Long projectId) {
		IssueCategoryStats queryParams = new IssueCategoryStats();
		queryParams.setCategoryId(categoryId);
		queryParams.setTrackerId(trackerId);
		queryParams.setPriorityId(priorityId);
		queryParams.setProjectId(projectId);

		List<IssueCategoryStats> statsList = categoryStatsMapper.selectIssueCategoryStatsList(queryParams);

		if (!CollectionUtils.isEmpty(statsList)) {
			return statsList.get(0);
		}

		// 如果没有统计数据，尝试从处理记录中实时计算
		return calculateRealtimeStats(categoryId, trackerId, priorityId, projectId);
	}

	@Override
	public List<IssueProcessingStats> getSimilarIssueHistory(Issue issue, Integer limit) {
		List<IssueProcessingStats> selectSimilarIssueHistory = processingStatsMapper.selectSimilarIssueHistory(
				issue.getCategoryId(), issue.getTrackerId(), issue.getPriorityId(), issue.getProjectId(),
				limit != null ? limit : 10);
		if (!selectSimilarIssueHistory.isEmpty()) {
			Map<Long, User> userMap = commonService.getUserMap();
			Map<Long, IssueStatus> issueStatusMap = commonService.getIssueStatusMap();
			selectSimilarIssueHistory.forEach(info -> {
				Long issueId = info.getIssueId();
				Issue issueInfo = issueService.getIssueInfoForCache(issueId);
				/** 关联信息 - 需求标题 */
				info.setIssueSubject(issueInfo != null ? issueInfo.getSubject() : "");
				/** 关联信息 - 项目名称 */
				info.setProjectName(issueInfo != null ? issueInfo.getProjectName() : "");
				/** 关联信息 - 发布者姓名 */
				Long authorId = info.getAuthorId();
				User authorUser = userMap.get(authorId);
				info.setAuthorName(authorUser != null ? authorUser.getUserName() : authorId == 1 ? "管理员" : "");
				/** 关联信息 - 处理人姓名 */
				Long assignedToId = info.getAssignedToId();
				User assignedToUser = userMap.get(assignedToId);
				info.setAssignedToName(
						assignedToUser != null ? assignedToUser.getUserName() : assignedToId == 1 ? "管理员" : "");
				/** 关联信息 - 原始状态名称 */
				IssueStatus fromStatus = issueStatusMap.get(info.getStatusFrom());
				info.setStatusFromName(fromStatus != null ? fromStatus.getName() : "");
				/** 关联信息 - 目标状态名称 */
				IssueStatus toStatus = issueStatusMap.get(info.getStatusTo());
				info.setStatusToName(toStatus != null ? toStatus.getName() : "");
				/** 关联信息 - 操作类型名称 */
				Integer operationType = info.getOperationType();
				info.setOperationTypeName(operationType == 1 ? "领取" : operationType == 2 ? "提交" : "审核");
			});
		}
		return selectSimilarIssueHistory;
	}

	@Override
	@Transactional
	public boolean recalculateCategoryStats(Long categoryId) {
		try {
			// 删除旧的统计记录
			categoryStatsMapper.deleteByCategoryId(categoryId);

			// 重新计算统计
			updateCategoryStats(categoryId);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	@Override
	public List<Map<String, Object>> getUserProcessingStats(Long userId, Integer limit) {
		return processingStatsMapper.selectUserProcessingStats(userId, limit != null ? limit : 10);
	}

	/**
	 * 计算处理时长
	 */
	private BigDecimal calculateProcessingHours(Long issueId, Integer operationType) {
		// 根据操作类型计算不同的处理时长
		if (operationType == 1) {
			// 领取操作，计算从发布到领取的时长
			Issue issue = issueMapper.selectIssuesById(issueId);
			if (issue != null && issue.getCreateTime() != null) {
				LocalDateTime createTime = issue.getCreateTime();
				Duration duration = Duration.between(createTime, LocalDateTime.now());
				return BigDecimal.valueOf(duration.toMinutes() / 60.0).setScale(2, RoundingMode.HALF_UP);
			}
		} else if (operationType == 2) {
			// 提交操作，计算从领取到提交的时长
			return processingStatsMapper.getProcessingTimeForOperation(issueId, 1, 2);
		} else if (operationType == 3) {
			// 审核操作，计算从提交到审核的时长
			return processingStatsMapper.getProcessingTimeForOperation(issueId, 2, 3);
		}

		return null;
	}

	/**
	 * 实时计算统计数据
	 */
	private IssueCategoryStats calculateRealtimeStats(Long categoryId, Long trackerId, Long priorityId,
			Long projectId) {
		Map<String, Object> statsData = processingStatsMapper.calculateStatsByCategory(categoryId, trackerId,
				priorityId, projectId);

		if (statsData == null || statsData.isEmpty()) {
			return null;
		}

		IssueCategoryStats stats = new IssueCategoryStats();
		stats.setCategoryId(categoryId);
		stats.setTrackerId(trackerId);
		stats.setPriorityId(priorityId);
		stats.setProjectId(projectId);

		Object sampleCount = statsData.get("total_count");
		if (sampleCount != null) {
			stats.setSampleCount(((Number) sampleCount).intValue());
		}

		Object avgTime = statsData.get("avg_processing_hours");
		if (avgTime != null) {
			stats.setAvgProcessingTimeHours(new BigDecimal(avgTime.toString()).setScale(2, RoundingMode.HALF_UP));
		}

		Object minTime = statsData.get("min_processing_hours");
		if (minTime != null) {
			stats.setMinProcessingTimeHours(new BigDecimal(minTime.toString()).setScale(2, RoundingMode.HALF_UP));
		}

		Object maxTime = statsData.get("max_processing_hours");
		if (maxTime != null) {
			stats.setMaxProcessingTimeHours(new BigDecimal(maxTime.toString()).setScale(2, RoundingMode.HALF_UP));
		}

		// 计算成功率（已完成数量 / 总数量）
		Object completedCount = statsData.get("completed_count");
		Object totalCount = statsData.get("total_count");
		if (completedCount != null && totalCount != null && ((Number) totalCount).intValue() > 0) {
			BigDecimal successRate = new BigDecimal(((Number) completedCount).doubleValue())
					.divide(new BigDecimal(((Number) totalCount).doubleValue()), 4, RoundingMode.HALF_UP)
					.multiply(new BigDecimal(100));
			stats.setSuccessRate(successRate.setScale(2, RoundingMode.HALF_UP));
		}

		// 计算重试率（更新数量 / 总数量）
		Object updateCount = statsData.get("update_count");
		if (updateCount != null && totalCount != null && ((Number) totalCount).intValue() > 0) {
			BigDecimal retryRate = new BigDecimal(((Number) updateCount).doubleValue())
					.divide(new BigDecimal(((Number) totalCount).doubleValue()), 4, RoundingMode.HALF_UP)
					.multiply(new BigDecimal(100));
			stats.setRetryRate(retryRate.setScale(2, RoundingMode.HALF_UP));
		}

		// 保存计算结果
		categoryStatsMapper.insertIssueCategoryStats(stats);

		return stats;
	}

	/**
	 * 更新类别统计
	 */
	private void updateCategoryStats(Long categoryId) {
		List<Long> categoryIds = new ArrayList<>();
		if (categoryId != null) {
			categoryIds.add(categoryId);
		} else {
			// 如果categoryId为null，则更新所有类别
			List<IssueCategoryStats> existingStats = categoryStatsMapper.selectDistinctCategoryIds();
			for (IssueCategoryStats stat : existingStats) {
				if (stat.getCategoryId() != null) {
					categoryIds.add(stat.getCategoryId());
				}
			}
		}

		for (Long catId : categoryIds) {
			// 获取该类别的不同组合
			List<Map<String, Object>> combinations = processingStatsMapper.selectCategoryCombinations(catId);

			for (Map<String, Object> combo : combinations) {
				Long trackerId = (Long) combo.get("tracker_id");
				Long priorityId = (Long) combo.get("priority_id");
				Long projectId = (Long) combo.get("project_id");

				// 删除旧统计
				categoryStatsMapper.deleteByCombination(catId, trackerId, priorityId, projectId);

				// 重新计算
				calculateRealtimeStats(catId, trackerId, priorityId, projectId);
			}
		}
	}

	/**
	 * 获取推荐处理人
	 */
	private Map<String, Object> getRecommendedAssignee(Issue issue) {
		Map<String, Object> result = new HashMap<>();

		// 基于同类需求的历史处理记录，找到处理时间最短、成功率最高的处理人
		Map<String, Object> recommended = processingStatsMapper.findRecommendedAssignee(issue.getCategoryId(),
				issue.getTrackerId(), issue.getPriorityId());

		if (recommended != null && !recommended.isEmpty()) {
			result.put("userId", recommended.get("assigned_to_id"));
			result.put("userName", recommended.get("assigned_to_name"));
			result.put("avgProcessingTime", recommended.get("avg_processing_time"));
			result.put("successCount", recommended.get("success_count"));
			result.put("totalCount", recommended.get("total_count"));
		}

		return result;
	}
}